package com.huwei.controller.valid;

import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import com.huwei.constant.JsonResult;
import com.huwei.constant.ResultErrorConstant;


@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {

	final private Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
	
	@ExceptionHandler(Throwable.class)
	public String unknow(Throwable e) {
		log.error(e.getMessage(),e);
		return JsonResult.failed(e.getMessage(),ResultErrorConstant.UNKNOW_ERROR);
	}
	
	@ExceptionHandler(RequestParamterError.class)
	public String requestParamterError(HttpServletRequest request ,HttpServletResponse response ,RequestParamterError e) {
		String reqResource = request.getScheme() +"://" + request.getServerName() 
			+":" + request.getServerPort() +request.getContextPath() + request.getRequestURI();
		log.debug(reqResource + " 请求，参数错误；参数列表：" + request.getQueryString());
		
		StringBuffer msg = new StringBuffer("参数错误");
		
		Errors errors = e.getError();
		if(errors.hasErrors()) {
			
			msg.append(": ");
			
			List<FieldError> fieldErrors = errors.getFieldErrors();
			for(int i = 0 ,len = fieldErrors.size() ;i < len ;++i) {
				FieldError fe = fieldErrors.get(i);
				String message = fe.getDefaultMessage();
				String fieldName = fe.getField();
				
				msg.append("参数-").append(fieldName).append("=>").append(Objects.isNull(message)?"缺少或错误":message).append(";");
			}
		}
		
		return JsonResult.failed(msg.toString(), ResultErrorConstant.PARAMTER_ERROR);
	}
	
	@ExceptionHandler(MissingServletRequestParameterException.class)
	public String missingServletRequestParameterException(MissingServletRequestParameterException ex) {
		log.debug("请求参数错误，缺少参数 :" + ex.getParameterName());
		return JsonResult.failed("缺少参数" + ex.getParameterName(), ResultErrorConstant.PARAMTER_MISS);
	}
	
	@ExceptionHandler(ConstraintViolationException.class)
	public String constraintViolationException(ConstraintViolationException e) {
		Set<ConstraintViolation<?>> violations =  e.getConstraintViolations();
		Iterator<ConstraintViolation<?>> iter = violations.iterator();
		
		StringBuffer sb = new StringBuffer();
		
		while(iter.hasNext()) {
			ConstraintViolation<?> violation = iter.next();
			sb.append(violation.getMessage()).append(",");
		}
		
		return JsonResult.failed(sb.toString(), ResultErrorConstant.PARAMTER_CONSTRAINT_VIOLATION);
	}
	
	@ExceptionHandler(MethodArgumentTypeMismatchException.class)
	public String numberFormatException(MethodArgumentTypeMismatchException ex) {
		return JsonResult.failed("参数格式不匹配：" + ex.getName(), ResultErrorConstant.PARAMTER_TYPE_MISMATCH);
	}
}
